package com.jiubodou.myoauth2.config;

import com.jiubodou.myoauth2.oauth2class.jiubodou.JiuBoDouTokenGranter;
import com.jiubodou.myoauth2.oauth2class.jiubodou.JiuBoDouTokenServices;
import com.jiubodou.myoauth2.oauth2class.my.MyTokenGranter;
import com.jiubodou.myoauth2.oauth2class.my.MyTokenServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import javax.sql.DataSource;
import java.util.ArrayList;

/**
 * @ClassName JiuBoDouOauth2Config
 * @Description
 * @Author huyingliang
 * @Date 2023/5/12 15:27
 */
@Configuration
public class JiuBoDouAndMyOauth2Config extends AuthorizationServerConfigurerAdapter {

    /*发现 tokenPoint 使用的是 内存中的数据去查询 client 所以这里需要指定 jdbc 来查询 client */
    @Autowired
    private DataSource dataSource;  /*告知数据源的相关信息*/

    @Bean
    public ClientDetailsService customClientDetailsService() {
        return new JdbcClientDetailsService(dataSource);/*将这个数据源信息给JdbcClientDetailsService*/
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(customClientDetailsService());/*指定使用 JdbcClientDetailsService来查找client*/
    }


    /*添加自己的 granter*/
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);

        JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
        DefaultOAuth2RequestFactory defaultOAuth2RequestFactory =
                new DefaultOAuth2RequestFactory(jdbcClientDetailsService);

        JiuBoDouTokenServices jiuBoDouTokenServices = new JiuBoDouTokenServices();
        jiuBoDouTokenServices.setTokenStore(redisTokenStore);

        MyTokenServices myTokenServices = new MyTokenServices();
        myTokenServices.setTokenStore(redisTokenStore);

        ArrayList<TokenGranter> tokenGranters = new ArrayList<>();

        JiuBoDouTokenGranter jiuBoDouTokenGranter = new JiuBoDouTokenGranter(authenticationManager, jiuBoDouTokenServices,
                jdbcClientDetailsService, defaultOAuth2RequestFactory);
        jiuBoDouTokenServices.setSupportRefreshToken(true); /*这里是设置 RefreshToken 的地方*/
        MyTokenGranter myTokenGranter = new MyTokenGranter(authenticationManager, myTokenServices,
                jdbcClientDetailsService, defaultOAuth2RequestFactory);

        tokenGranters.add(jiuBoDouTokenGranter);
        tokenGranters.add(myTokenGranter);
        CompositeTokenGranter compositeTokenGranter = new CompositeTokenGranter(tokenGranters);

        endpoints.tokenGranter(compositeTokenGranter);

//        /*这里不能使用 endpoints.tokenGranter一直添加自己的 granter 要使用上面的方法*/
//        endpoints.tokenGranter(new JiuBoDouTokenGranter(authenticationManager, jiuBoDouTokenServices,
//                jdbcClientDetailsService, defaultOAuth2RequestFactory));
//        endpoints.tokenGranter(new MyTokenGranter(authenticationManager, myTokenServices,
//                jdbcClientDetailsService, defaultOAuth2RequestFactory));
    }


}
